<template>
    <div class="gv-monaco-editor" :ref="ref"
         :style="[disable ? {'pointer-events': 'none'} : '', {'height': height + 'px'}]"/>
</template>
<script lang="ts">
/**
 * 官方文档：  https://microsoft.github.io/monaco-editor/index.html
 * 构造器配置地址： https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditorconstructionoptions.html
 * @author 何挺强
 * @date 2021-09-09 11:58
 */
import * as monaco from 'monaco-editor';
import './uuid';

export default {
    name: 'MonacoEditor',
    props: {
        value: {
            default: ''
        },
        disable: {
            type: Boolean,
            default: false
        },
        /**
         *  可配置值： vs, hc-black, or vs-dark
         */
        theme: {
            type: String,
            default: 'vs'
        },
        language: {
            type: String,
            default: 'json'
        },
        height: {
            type: Number,
            default: 200
        },
        options: Object
    },
    data() {
        return {
            currentVal: this.value,
            ref: Math.uuid(),
            monacoEditor: null,
            //json 编辑器
            jsonEditor: {
                lineNumbers: 'off',
                minimap: {
                    enabled: false
                }
            }
        }
    },
    mounted() {
        this.$nextTick(() => {
            this.init();
        })
    },
    methods: {
        /**
         * 内容格式化
         * @date 2021-09-09 14:05
         */
        format() {
            if (!this.monacoEditor) {
                return;
            }

            this.monacoEditor.getAction(['editor.action.formatDocument'])._run();
        },
        init() {
            //已经初始化过了
            if (this.monacoEditor) {
                return;
            }
            //配置参数设置
            let options = {
                value: this.currentVal,
                language: this.language,
                theme: this.theme || 'vs',
                readOnly: false,
            }
            //根据语言,追加默认配置
            switch (options.language.toLowerCase()) {
                case 'json':
                    options = Object.assign(options, this.jsonEditor);
                    break;
            }
            //追加自定义配置
            options = Object.assign(options, this.options || {});
            options.readOnly = this.disable;

            let editDom = this.$refs[this.ref];
            editDom.innerHTML = ''
            this.monacoEditor = monaco.editor.create(editDom, options);
            //内容变化
            this.monacoEditor.onDidChangeModelContent(() => {
                this.currentVal = this.monacoEditor.getValue();
                this.$emit("update:value", this.currentVal);
                this.$emit("change", this.currentVal);
            });
        }
    },
    watch: {
        value(val) {
            //如果当前值一样,或编辑器未初始化,就不做处理
            if (this.currentVal === val || !this.monacoEditor) {
                return;
            }
            this.currentVal = val;
            this.monacoEditor.setValue(this.currentVal);
        }
    }
}
</script>
<style scoped>
.gv-monaco-editor {
    width: 100%;
    /* height: 500px; */
    border: 1px solid gainsboro;
    margin: 0;
    padding: 0;
}
</style>
